#include "Vector.h"
#include <iostream>
#include <ctime>
#include <vector>

using std::cout;
using std::endl;

int functionalTest()
{
    cout << "Functional Test: " << endl;
    cout << "Create Vector<int> a(10)" << endl;
    Vector<int> a(10);
    cout << "Use operator [] to make a[i]=i for i = 0,...,9" << endl;
    for(int i = 0; i < 10; i++)
        a[i] = i;
    cout << "Test output stream" << endl;
    cout << "    a = " << a << endl;
    cout << "    a.size() = " << a.size() << endl;
    cout << "    a.capacity() = " << a.capacity() << endl;
    cout << "Use iterator to make a[i]=i+1 for i = 0,...,9" << endl;
    int cnt = 1;
    for(Vector<int>::iterator it = a.begin(); it != a.end(); it++)
    {
        *it = cnt;
        cnt++;
    }
    cout << "    a = " << a << endl;
    cout << "    a.size() = " << a.size() << endl;
    cout << "    a.capacity() = " << a.capacity() << endl;
    cout << "Test push_back():" << endl;
    for(int i = 11; i <= 15; i++)
    {
        a.push_back(i);
        cout << "    a = " << a << endl;
        cout << "    a.size() = " << a.size() << endl;
        cout << "    a.capacity() = " << a.capacity() << endl;
    }
    cout << "Test pop_back():" << endl;
    for(int i = 0; i < 3; i++)
    {
        a.pop_back();
        cout << "    a = " << a << endl;
        cout << "    a.size() = " << a.size() << endl;
        cout << "    a.capacity() = " << a.capacity() << endl;
    }
    cout << "Test pop_front():" << endl;
    for(int i = 0; i < 3; i++)
    {
        a.pop_front();
        cout << "    a = " << a << endl;
        cout << "    a.size() = " << a.size() << endl;
        cout << "    a.capacity() = " << a.capacity() << endl;
    }
    cout << "Test reverse():" << endl;
    a.reverse();
    cout << "    a = " << a << endl;
    cout << "    a.size() = " << a.size() << endl;
    cout << "    a.capacity() = " << a.capacity() << endl;
    cout << "Test empty():" << endl;
    cout << "    a.empty() = " << a.empty() << endl;
    cout << "Test back():" << endl;
    cout << "    a.back() = " << a.back() << endl;
    cout << "Test operator = :" << endl;
    Vector<int> b = a;
    cout << "    a = " << a << endl;
    cout << "    a.size() = " << a.size() << endl;
    cout << "    a.capacity() = " << a.capacity() << endl;
    cout << "    b = " << b << endl;
    cout << "    b.size() = " << b.size() << endl;
    cout << "    b.capacity() = " << b.capacity() << endl;
    cout << "Let b[0] = 100 to verify that a and b are different:" << endl;
    b[0] = 100;
    cout << "    a = " << a << endl;
    cout << "    a.size() = " << a.size() << endl;
    cout << "    a.capacity() = " << a.capacity() << endl;
    cout << "    b = " << b << endl;
    cout << "    b.size() = " << b.size() << endl;
    cout << "    b.capacity() = " << b.capacity() << endl;
    cout << "Functional test finished. Everything is OK." << endl;
    cout << "---------------------------------------------------------------------------------" << endl;
    return 0;
}

int runTest(const int & n)
{
    int iBeginTime = clock();
    Vector<int> a;
    for(int i = 0; i < n; i++)
        a.push_back(i);
    return (double)(clock() - iBeginTime) / CLOCKS_PER_SEC * 1000;
}

int runTestSTL(const int & n)
{
    int iBeginTime = clock();
    std::vector<int> a;
    for(int i = 0; i < n; i++)
        a.push_back(i);
    return (double)(clock() - iBeginTime) / CLOCKS_PER_SEC * 1000;
}


void spareCapacityTest()
{
    cout << "Spare Capacity Test: " << endl;
    static const int N = 10000000;
    static const int T = 1000;
    int iAllTIme = 0;
    for(int t = 0; t < T; t++)
    {
        int n = rand() % N;
        int tmp = runTest(n);
        iAllTIme += tmp;
        cout << "    Test " << t << ": n=" << n << " time=" << tmp << "ms" << endl;
    }
    cout << "Averange Time: " << iAllTIme / T << "ms" << endl;
    cout << "Spare capacity test finished." << endl;
    cout << "---------------------------------------------------------------------------------" << endl;
}

void comparableTest()
{
    cout << "Comparable Test: " << endl;
    static const int N = 10000000;
    static const int T = 1000;
    int iAllTIme = 0, iAllTIme2 = 0;
    for(int t = 0; t < T; t++)
    {
        int n = rand() % N;
        int tmp = runTest(n);
        int tmp2 = runTestSTL(n);
        cout << "    Test " << t << ": n=" << n << " my_time=" << tmp << "ms  STL_time=" << tmp2 << endl;
        iAllTIme += tmp;
        iAllTIme2 += tmp2;
    }
    cout << "My Vector Averange Time: " << iAllTIme / T << "ms" << endl;
    cout << "STL Vector Averange Time: " << iAllTIme2 / T << "ms" << endl;
    cout << "Comparable test finished." << endl;
    cout << "---------------------------------------------------------------------------------" << endl;
}

int main()
{
    functionalTest();
    spareCapacityTest();
    comparableTest();
    return 0;
}